using Baci.Net.ToolKit.ArcGISProGeoprocessor.Models;
using Baci.Net.ToolKit.ArcGISProGeoprocessor.Models.Attributes;
using Baci.Net.ToolKit.ArcGISProGeoprocessor.Models.Attributes.DomainAttributes;
using Baci.Net.ToolKit.ArcGISProGeoprocessor.Models.Enums;
using System.Collections.Generic;
using System.ComponentModel;

namespace Baci.ArcGIS._3DAnalystTools._PointCloud._Classification
{
    /// <summary>
    /// <para>Train Point Cloud Classification Model</para>
    /// <para>Trains a deep learning model for point cloud classification using the PointCNN architecture.</para>
    /// <para>使用 PointCNN 架构训练用于点云分类的深度学习模型。</para>
    /// </summary>    
    [DisplayName("Train Point Cloud Classification Model")]
    public class TrainPointCloudClassificationModel : AbstractGPProcess
    {
        /// <summary>
        /// 无参构造
        /// </summary>
        public TrainPointCloudClassificationModel()
        {

        }

        /// <summary>
        /// 有参构造
        /// </summary>
        /// <param name="_in_training_data">
        /// <para>Input Training Data</para>
        /// <para>The point cloud training data (*.pctd) that will be used to train the classification model.</para>
        /// <para>将用于训练分类模型的点云训练数据 （*.pctd）。</para>
        /// </param>
        /// <param name="_out_model_location">
        /// <para>Output Model Location</para>
        /// <para>The existing folder that will store the new directory containing the deep learning model.</para>
        /// <para>将存储包含深度学习模型的新目录的现有文件夹。</para>
        /// </param>
        /// <param name="_out_model_name">
        /// <para>Output Model Name</para>
        /// <para>The name of the output Esri model definition file (*.emd), deep learning package (*.dlpk), and the new directory that will be created to store them.</para>
        /// <para>输出 Esri 模型定义文件 （*.emd）、深度学习包 （*.dlpk） 的名称，以及将创建用于存储它们的新目录。</para>
        /// </param>
        public TrainPointCloudClassificationModel(object _in_training_data, object _out_model_location, object _out_model_name)
        {
            this._in_training_data = _in_training_data;
            this._out_model_location = _out_model_location;
            this._out_model_name = _out_model_name;
        }
        public override string ToolboxName => "3D Analyst Tools";

        public override string ToolName => "Train Point Cloud Classification Model";

        public override string CallName => "3d.TrainPointCloudClassificationModel";

        public override List<string> AcceptEnvironments => ["gpuID", "processorType"];

        public override object[] ParameterInfo => [_in_training_data, _out_model_location, _out_model_name, _pretrained_model, _attributes, _min_points, _class_remap, _target_classes, _background_class, _class_descriptions, _model_selection_criteria.GetGPValue(), _max_epochs, _epoch_iterations, _learning_rate, _batch_size, _early_stop.GetGPValue(), _out_model, _out_model_stats];

        /// <summary>
        /// <para>Input Training Data</para>
        /// <para>The point cloud training data (*.pctd) that will be used to train the classification model.</para>
        /// <para>将用于训练分类模型的点云训练数据 （*.pctd）。</para>
        /// <para></para>
        /// </summary>
        [DisplayName("Input Training Data")]
        [Description("")]
        [Option(OptionTypeEnum.Must)]
        public object _in_training_data { get; set; }


        /// <summary>
        /// <para>Output Model Location</para>
        /// <para>The existing folder that will store the new directory containing the deep learning model.</para>
        /// <para>将存储包含深度学习模型的新目录的现有文件夹。</para>
        /// <para></para>
        /// </summary>
        [DisplayName("Output Model Location")]
        [Description("")]
        [Option(OptionTypeEnum.Must)]
        public object _out_model_location { get; set; }


        /// <summary>
        /// <para>Output Model Name</para>
        /// <para>The name of the output Esri model definition file (*.emd), deep learning package (*.dlpk), and the new directory that will be created to store them.</para>
        /// <para>输出 Esri 模型定义文件 （*.emd）、深度学习包 （*.dlpk） 的名称，以及将创建用于存储它们的新目录。</para>
        /// <para></para>
        /// </summary>
        [DisplayName("Output Model Name")]
        [Description("")]
        [Option(OptionTypeEnum.Must)]
        public object _out_model_name { get; set; }


        /// <summary>
        /// <para>Pre-trained Model</para>
        /// <para>The pretrained model that will be refined. When a pretrained model is provided, the input training data must have the same attributes, class codes, and maximum number of points that were used by the training data that generated this model.</para>
        /// <para>将要优化的预训练模型。提供预训练模型时，输入训练数据必须具有与生成此模型的训练数据使用的相同属性、类代码和最大点数。</para>
        /// <para></para>
        /// </summary>
        [DisplayName("Pre-trained Model")]
        [Description("")]
        [Option(OptionTypeEnum.optional)]
        public object _pretrained_model { get; set; } = null;


        /// <summary>
        /// <para>Attribute Selection</para>
        /// <para><xdoc>
        ///   <para>Specifies the point attributes that will be used with the classification code when training the model. Only the attributes that are present in the point cloud training data will be available. No additional attributes are included by default.</para>
        ///   <bulletList>
        ///     <bullet_item>Intensity—The measure of the magnitude of the lidar pulse return will be used.</bullet_item><para/>
        ///     <bullet_item>Return Number—The ordinal position of the point obtained from a given lidar pulse will be used.</bullet_item><para/>
        ///     <bullet_item>Number of Returns—The total number of lidar returns that were identified as points from the pulse associated with a given point will be used.</bullet_item><para/>
        ///     <bullet_item>Red Band—The red band's value from a point cloud with color information will be used.</bullet_item><para/>
        ///     <bullet_item>Green Band—The green band's value from a point cloud with color information will be used.</bullet_item><para/>
        ///     <bullet_item>Blue Band—The blue band's value from a point cloud with color information will be used.</bullet_item><para/>
        ///     <bullet_item>Near Infrared Band—The near infrared band's value from a point cloud with near infrared information will be used.</bullet_item><para/>
        ///   </bulletList>
        /// </xdoc></para>
        /// <para><xdoc>
        ///   <para>指定在训练模型时将与分类代码一起使用的点属性。只有点云训练数据中存在的属性才可用。默认情况下不包含其他属性。</para>
        ///   <bulletList>
        ///     <bullet_item>强度—将使用激光雷达脉冲回波幅度的度量。</bullet_item><para/>
        ///     <bullet_item>返回编号—将使用从给定激光雷达脉冲获得的点的序号位置。</bullet_item><para/>
        ///     <bullet_item>回波数 - 将使用从与给定点关联的脉冲中标识为点的激光雷达回波总数。</bullet_item><para/>
        ///     <bullet_item>红色波段—将使用具有颜色信息的点云中的红色波段值。</bullet_item><para/>
        ///     <bullet_item></bullet_item><para/>
        ///     <bullet_item></bullet_item><para/>
        ///     <bullet_item>近红外波段—将使用具有近红外信息的点云的近红外波段值。</bullet_item><para/>
        ///   </bulletList>
        /// </xdoc></para>
        /// <para></para>
        /// </summary>
        [DisplayName("Attribute Selection")]
        [Description("")]
        [Option(OptionTypeEnum.optional)]
        public List<object> _attributes { get; set; } = null;


        /// <summary>
        /// <para>Minimum Points Per Block</para>
        /// <para>The minimum number of points that must be present in a given block for it to be used when training the model. The default is 0.</para>
        /// <para>在训练模型时，给定块中必须存在的最小点数，以便使用它。默认值为 0。</para>
        /// <para></para>
        /// </summary>
        [DisplayName("Minimum Points Per Block")]
        [Description("")]
        [Option(OptionTypeEnum.optional)]
        public long _min_points { get; set; } = 0;


        /// <summary>
        /// <para>Class Remapping</para>
        /// <para>Defines how class code values will map to new values prior to training the deep learning model.</para>
        /// <para>定义在训练深度学习模型之前，类代码值将如何映射到新值。</para>
        /// <para></para>
        /// </summary>
        [DisplayName("Class Remapping")]
        [Description("")]
        [Option(OptionTypeEnum.optional)]
        public object _class_remap { get; set; } = null;


        /// <summary>
        /// <para>Class Codes Of Interest</para>
        /// <para>The class codes that will be used to filter the blocks in the training data. When class codes of interest are specified, all other class codes are remapped to the background class code.</para>
        /// <para>将用于筛选训练数据中的块的类代码。指定感兴趣的类代码时，所有其他类代码将重新映射到后台类代码。</para>
        /// <para></para>
        /// </summary>
        [DisplayName("Class Codes Of Interest")]
        [Description("")]
        [Option(OptionTypeEnum.optional)]
        public List<object> _target_classes { get; set; } = null;


        /// <summary>
        /// <para>Background Class Code</para>
        /// <para>The class code value that will be used for all other class codes when class codes of interest have been specified.</para>
        /// <para>指定感兴趣的类代码时将用于所有其他类代码的类代码值。</para>
        /// <para></para>
        /// </summary>
        [DisplayName("Background Class Code")]
        [Description("")]
        [Option(OptionTypeEnum.optional)]
        public long? _background_class { get; set; } = null;


        /// <summary>
        /// <para>Class Description</para>
        /// <para>The descriptions of what each class code in the training data represents.</para>
        /// <para>训练数据中每个类代码所表示内容的说明。</para>
        /// <para></para>
        /// </summary>
        [DisplayName("Class Description")]
        [Description("")]
        [Option(OptionTypeEnum.optional)]
        public object _class_descriptions { get; set; } = null;


        /// <summary>
        /// <para>Model Selection Criteria</para>
        /// <para><xdoc>
        ///   <para>Specifies the statistical basis that will be used to determine the final model.</para>
        ///   <bulletList>
        ///     <bullet_item>Validation Loss—The model that achieves the lowest result when the entropy loss function is applied to the validation data will be selected.</bullet_item><para/>
        ///     <bullet_item>Recall—The model that achieves the best macro average of the recall for all class codes will be selected. Each class code's recall value is determined by the ratio of correctly classified points (true positives) over all the points that should have been classified with this value (expected positives). This is the default.</bullet_item><para/>
        ///     <bullet_item>F1 Score—The model that achieves the best harmonic mean between the macro average of the precision and recall values for all class codes will be selected. This provides a balance between precision and recall, which favors better overall performance.</bullet_item><para/>
        ///     <bullet_item>Precision—The model that achieves the best macro average of the precision for all class codes will be selected. Each class code's precision is determined by the ratio of points that are correctly classified (true positives) over all the points that are classified (true positives and false positives).</bullet_item><para/>
        ///     <bullet_item>Accuracy—The model that achieves the highest ratio of corrected classified points over all the points in the validation data will be selected.</bullet_item><para/>
        ///   </bulletList>
        /// </xdoc></para>
        /// <para><xdoc>
        ///   <para>指定将用于确定最终模型的统计基础。</para>
        ///   <bulletList>
        ///     <bullet_item>验证损失—将选择将熵损失函数应用于验证数据时获得最低结果的模型。</bullet_item><para/>
        ///     <bullet_item>召回—将选择实现所有类代码召回率最佳宏平均值的模型。每个类代码的召回率值由正确分类的点（真阳性）与应使用此值分类的所有点（预期阳性）的比率确定。这是默认设置。</bullet_item><para/>
        ///     <bullet_item>F1 分数—将选择在精度的宏观平均值和召回率值之间实现最佳谐波均值的模型。这在精确度和召回率之间提供了平衡，有利于更好的整体性能。</bullet_item><para/>
        ///     <bullet_item>精度—将选择实现所有类代码精度的最佳宏观平均值的模型。每个类代码的精度由正确分类的点（真阳性）与所有分类的点（真阳性和假阳性）的比率决定。</bullet_item><para/>
        ///     <bullet_item>准确度—将选择校正分类点在验证数据中所有点中达到最高比率的模型。</bullet_item><para/>
        ///   </bulletList>
        /// </xdoc></para>
        /// <para></para>
        /// </summary>
        [DisplayName("Model Selection Criteria")]
        [Description("")]
        [Option(OptionTypeEnum.optional)]
        public _model_selection_criteria_value _model_selection_criteria { get; set; } = _model_selection_criteria_value._RECALL;

        public enum _model_selection_criteria_value
        {
            /// <summary>
            /// <para>Validation Loss</para>
            /// <para>Validation Loss—The model that achieves the lowest result when the entropy loss function is applied to the validation data will be selected.</para>
            /// <para>验证损失—将选择将熵损失函数应用于验证数据时获得最低结果的模型。</para>
            /// </summary>
            [Description("Validation Loss")]
            [GPEnumValue("VALIDATION_LOSS")]
            _VALIDATION_LOSS,

            /// <summary>
            /// <para>Recall</para>
            /// <para>Recall—The model that achieves the best macro average of the recall for all class codes will be selected. Each class code's recall value is determined by the ratio of correctly classified points (true positives) over all the points that should have been classified with this value (expected positives). This is the default.</para>
            /// <para>召回—将选择实现所有类代码召回率最佳宏平均值的模型。每个类代码的召回率值由正确分类的点（真阳性）与应使用此值分类的所有点（预期阳性）的比率确定。这是默认设置。</para>
            /// </summary>
            [Description("Recall")]
            [GPEnumValue("RECALL")]
            _RECALL,

            /// <summary>
            /// <para>F1 Score</para>
            /// <para>F1 Score—The model that achieves the best harmonic mean between the macro average of the precision and recall values for all class codes will be selected. This provides a balance between precision and recall, which favors better overall performance.</para>
            /// <para>F1 分数—将选择在精度的宏观平均值和召回率值之间实现最佳谐波均值的模型。这在精确度和召回率之间提供了平衡，有利于更好的整体性能。</para>
            /// </summary>
            [Description("F1 Score")]
            [GPEnumValue("F1_SCORE")]
            _F1_SCORE,

            /// <summary>
            /// <para>Precision</para>
            /// <para>Precision—The model that achieves the best macro average of the precision for all class codes will be selected. Each class code's precision is determined by the ratio of points that are correctly classified (true positives) over all the points that are classified (true positives and false positives).</para>
            /// <para>精度—将选择实现所有类代码精度的最佳宏观平均值的模型。每个类代码的精度由正确分类的点（真阳性）与所有分类的点（真阳性和假阳性）的比率决定。</para>
            /// </summary>
            [Description("Precision")]
            [GPEnumValue("PRECISION")]
            _PRECISION,

            /// <summary>
            /// <para>Accuracy</para>
            /// <para>Accuracy—The model that achieves the highest ratio of corrected classified points over all the points in the validation data will be selected.</para>
            /// <para>准确度—将选择校正分类点在验证数据中所有点中达到最高比率的模型。</para>
            /// </summary>
            [Description("Accuracy")]
            [GPEnumValue("ACCURACY")]
            _ACCURACY,

        }

        /// <summary>
        /// <para>Maximum Number of Epochs</para>
        /// <para>The number of times each block of data is passed forward and backward through the neural network. The default is 25.</para>
        /// <para>每个数据块通过神经网络向前和向后传递的次数。默认值为 25。</para>
        /// <para></para>
        /// </summary>
        [DisplayName("Maximum Number of Epochs")]
        [Description("")]
        [Option(OptionTypeEnum.optional)]
        public long _max_epochs { get; set; } = 25;


        /// <summary>
        /// <para>Iterations Per Epoch (%)</para>
        /// <para>The percentage of the data that is processed in each training epoch. The default is 100.</para>
        /// <para>每个训练周期中处理的数据的百分比。默认值为 100。</para>
        /// <para></para>
        /// </summary>
        [DisplayName("Iterations Per Epoch (%)")]
        [Description("")]
        [Option(OptionTypeEnum.optional)]
        public double _epoch_iterations { get; set; } = 100;


        /// <summary>
        /// <para>Learning Rate</para>
        /// <para>The rate at which existing information will be overwritten with new information. If no value is specified, the optimal learning rate will be extracted from the learning curve during the training process. This is the default.</para>
        /// <para>现有信息被新信息覆盖的速率。如果未指定值，则将在训练过程中从学习曲线中提取最佳学习率。这是默认设置。</para>
        /// <para></para>
        /// </summary>
        [DisplayName("Learning Rate")]
        [Description("")]
        [Option(OptionTypeEnum.optional)]
        public double? _learning_rate { get; set; } = null;


        /// <summary>
        /// <para>Batch Size</para>
        /// <para>The number of training data blocks that will be processed at any given time. The default is 2.</para>
        /// <para>在任何给定时间将处理的训练数据块的数量。默认值为 2。</para>
        /// <para></para>
        /// </summary>
        [DisplayName("Batch Size")]
        [Description("")]
        [Option(OptionTypeEnum.optional)]
        public long _batch_size { get; set; } = 2;


        /// <summary>
        /// <para>Stop training when model no longer improves</para>
        /// <para><xdoc>
        ///   <para>Specifies whether the model training will stop when the value specified for the Model Selection Criteria parameter does not register any improvement after 5 consecutive epochs.</para>
        ///   <bulletList>
        ///     <bullet_item>Checked—The model training will stop when the model is no longer improving. This is the default.</bullet_item><para/>
        ///     <bullet_item>Unchecked—The model training will continue until the maximum number of epochs has been reached.</bullet_item><para/>
        ///   </bulletList>
        /// </xdoc></para>
        /// <para><xdoc>
        ///   <para>指定当为“模型选择条件”参数指定的值在连续 5 个周期后未记录任何改进时，模型训练是否将停止。</para>
        ///   <bulletList>
        ///     <bullet_item>选中 - 当模型不再改进时，模型训练将停止。这是默认设置。</bullet_item><para/>
        ///     <bullet_item>未选中—模型训练将继续进行，直到达到最大 epoch 数。</bullet_item><para/>
        ///   </bulletList>
        /// </xdoc></para>
        /// <para></para>
        /// </summary>
        [DisplayName("Stop training when model no longer improves")]
        [Description("")]
        [Option(OptionTypeEnum.optional)]
        public _early_stop_value _early_stop { get; set; } = _early_stop_value._true;

        public enum _early_stop_value
        {
            /// <summary>
            /// <para>EARLY_STOP</para>
            /// <para></para>
            /// <para></para>
            /// </summary>
            [Description("EARLY_STOP")]
            [GPEnumValue("true")]
            _true,

            /// <summary>
            /// <para>NO_EARLY_STOP</para>
            /// <para></para>
            /// <para></para>
            /// </summary>
            [Description("NO_EARLY_STOP")]
            [GPEnumValue("false")]
            _false,

        }

        /// <summary>
        /// <para>Output Model</para>
        /// <para></para>
        /// <para></para>
        /// <para></para>
        /// </summary>
        [DisplayName("Output Model")]
        [Description("")]
        [Option(OptionTypeEnum.derived)]
        public object _out_model { get; set; }


        /// <summary>
        /// <para>Output Model Statistics</para>
        /// <para></para>
        /// <para></para>
        /// <para></para>
        /// </summary>
        [DisplayName("Output Model Statistics")]
        [Description("")]
        [Option(OptionTypeEnum.derived)]
        public object _out_model_stats { get; set; }


        public TrainPointCloudClassificationModel SetEnv()
        {
            base.SetEnv();
            return this;
        }

    }

}